/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package intopo.evogame.partnerselection.player;

import intopo.evogame.partnerselection.chromosome.Chromosome;
import intopo.evogame.partnerselection.population.Node;
import intopo.game.Strategy;
import java.io.IOException;

/**
 * Plain players do not have extra fields besides the ones declared in class {@code AbstractPlayer}.  They select partners using the algorithm provided in method {@code AbstractPlayer#playGame()}.
 * This kind of player never dies of internal causes. Only due to carrying capacity.
 *
 * @see intopo.evogame.partnerselection.player.AbstractPlayer#playGame(int, intopo.game.Game, intopo.game.Game.Strategies, intopo.evogame.partnerselection.player.AbstractPlayer[])
 *
 * @author <a href="mailto:mariano.pedro@gmail.com">Pedro Mariano</a>
 *
 * @version 1.0 __DATE__
 */
final public class PlainPlayer<S extends Strategy<S>>
	extends AbstractPlayer<S, Chromosome<S>, PlainPlayer<S>>
{
	/**
	 * Construct a plain player with the given chromosome.
	 * @param c
	 */
	public PlainPlayer (Chromosome<S> c, int parentID, Node<S, Chromosome<S>, PlainPlayer<S>> node, int bornTime)
		throws IOException
	{
		super (c, parentID, node, bornTime);
	}

	/**
	 * Return the chromosome of the offspring if this player is capable of reproducing.  If this
	 * player cannot reproduce {@code null} is returned.
	 *
	 * <p> Reproduction occurs if this player's energy has reached the reproduction threshold.  This is a global parameter that effects the behaviour of all instances of class {@code PlainPlayer}.
	 * After reproducing the energy goes back to zero.
	 *
	 * @return the chromosome of the offspring if this player is capable of reproducing.
	 *
	 * @throws java.io.IOException If there is an error writing the chromosome to the database.
	 */
	@Override
	public Chromosome<S> reproduction ()
		throws IOException
	{
		if (this.energy >= AbstractPlayer.Parameters.energyReproduction) {
			this.energy -= AbstractPlayer.Parameters.energyReproduction;
			return this.chromosome.reproduce ();
		}
		else {
			return null;
		}
	}

	/**
	 * Plain players never die of internal causes.  Only from carrying capacity.
	 * @return {@code false}.
	 */
	@Override
	public boolean dies ()
	{
		return false;
	}

	/**
	 * Return a factory of {@code PlainPlayer<S1>} instances.
	 * <p> These players do not have a parent.  Field {@code Parent.parentID} is initialised to -1.
	 * @param <S1> The strategy used by {@code PlainPlayer} instances.
	 * @return a factory of {@code PlainPlayer<S1>} instances.
	 */
	static public <S1 extends Strategy<S1>> PlayerFactory<S1, Chromosome<S1>, PlainPlayer<S1>> getFactory ()
	{
		return new PlainPlayer.Factory<S1> ();
	}
	/**
	 * Private class that implements the {@code PlayerFactory} interface.
	 * Classes that extend {@code AbstractPlayer} have a static method that return a factory.
	 * @param <S>
	 */
	static private class Factory<S extends Strategy<S>>
		implements PlayerFactory<S, Chromosome<S>, PlainPlayer<S>>

	{
		@Override
		public PlainPlayer<S> create (Chromosome<S> c, Node<S, Chromosome<S>, PlainPlayer<S>> node, int bornTime)
			throws IOException
		{
			return new PlainPlayer<S> (c, AbstractPlayer.NO_PARENT, node, bornTime);
		}

		@Override
		public PlainPlayer<S> create (Chromosome<S> c, int parentID, Node<S, Chromosome<S>, PlainPlayer<S>> node, int bornTime)
			throws IOException
		{
			return new PlainPlayer<S> (c, parentID, node, bornTime);
		}
	}
}

// Local Variables:
// mode: java
// mode: flyspell-prog
// ispell-local-dictionary: "british"
// End:
